home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Installer SDK 1.2.3 / Upgrader 1.2.3 & Engines / Upgrader 1.2.3 / Plug-in Examples / Common Files / Editor Utilities / LStyledTextEdit.cp < prev    next >
Encoding:
Text File  |  1997-06-21  |  19.4 KB  |  791 lines  |  [TEXT/CWIE]

  1. // ===========================================================================
  2. //    LTextEdit.cp               ©1993-1996 Metrowerks Inc. All rights reserved.
  3. // ===========================================================================
  4. //
  5. //    ### Still under moderate construction
  6. //            * Doesn't autoscroll while typing or selecting
  7. //            * Doesn't adjust to display whole lines
  8. //            * Doesn't undo
  9.  
  10. #ifdef PowerPlant_PCH
  11. #include PowerPlant_PCH
  12. #endif
  13.  
  14. #include "LStyledTextEdit.h"
  15.  
  16. #include <LStream.h>
  17. #include <UTextTraits.h>
  18. #include <UDrawingState.h>
  19. #include <UMemoryMgr.h>
  20. #include <UKeyFilters.h>
  21. #include <PP_KeyCodes.h>
  22. #include <PP_Messages.h>
  23.  
  24. #ifndef __SCRAP__
  25. #include <Scrap.h>
  26. #endif
  27.  
  28. #ifndef __SCRIPT__
  29. #include <Script.h>
  30. #endif
  31.  
  32. #ifndef __TOOLUTILS__
  33. #include <ToolUtils.h>
  34. #endif
  35.  
  36.  
  37. // ---------------------------------------------------------------------------
  38. //        • CreateStyledTextEditStream
  39. // ---------------------------------------------------------------------------
  40. //    Create a new StyledTextEdit object from the data in a Stream
  41.  
  42. LStyledTextEdit*
  43. LStyledTextEdit::CreateStyledTextEditStream(
  44.     LStream    *inStream)
  45. {
  46.     return (new LStyledTextEdit(inStream));
  47. }
  48.  
  49.  
  50. // ---------------------------------------------------------------------------
  51. //        • LStyledTextEdit
  52. // ---------------------------------------------------------------------------
  53. //    Default Contructor
  54.  
  55. LStyledTextEdit::LStyledTextEdit()
  56. {
  57.     mTextAttributes = 0;
  58.     InitStyledTextEdit(0);            // Initialize member variables
  59.     AlignTextEditRects();
  60. }
  61.  
  62.  
  63. // ---------------------------------------------------------------------------
  64. //        • LStyledTextEdit
  65. // ---------------------------------------------------------------------------
  66. //    Construct from input parameters
  67.  
  68. LStyledTextEdit::LStyledTextEdit(
  69.     const SPaneInfo    &inPaneInfo,
  70.     const SViewInfo    &inViewInfo,
  71.     Uint16            inTextAttributes,
  72.     ResIDT            inTextTraitsID)
  73.         : LView(inPaneInfo, inViewInfo)
  74. {
  75.     mTextAttributes = inTextAttributes;
  76.     InitStyledTextEdit(inTextTraitsID);
  77.     AlignTextEditRects();
  78. }
  79.  
  80.  
  81. // ---------------------------------------------------------------------------
  82. //        • LStyledTextEdit(LStream*)
  83. // ---------------------------------------------------------------------------
  84. //    Contruct an StyledTextEdit from the data in a Stream
  85.  
  86. LStyledTextEdit::LStyledTextEdit(
  87.     LStream    *inStream)
  88.         : LView(inStream)
  89. {
  90.     inStream->ReadData(&mTextAttributes, sizeof(Uint16));
  91.  
  92.     ResIDT    textTraitsID;
  93.     inStream->ReadData(&textTraitsID, sizeof(ResIDT));
  94.     
  95.     ResIDT    initialTextID;
  96.     inStream->ReadData(&initialTextID, sizeof(ResIDT));
  97.     
  98.     InitStyledTextEdit(textTraitsID);
  99.     AlignTextEditRects();
  100.     
  101.     Handle    initialTextH = ::GetResource('TEXT', initialTextID);
  102.     if (initialTextH != nil) {
  103.         SetTextHandle(initialTextH);
  104.         ::ReleaseResource(initialTextH);
  105.         ::TESetSelect(0, 0, mTextEditH);
  106.     }
  107. }
  108.  
  109.  
  110. // ---------------------------------------------------------------------------
  111. //        • InitStyledTextEdit
  112. // ---------------------------------------------------------------------------
  113. //    Initialize member variables of a StyledTextEdit to default values
  114.  
  115. void
  116. LStyledTextEdit::InitStyledTextEdit(
  117.     ResIDT    inTextTraitsID)
  118. {
  119.     Rect    viewRect = {0, 0, 0, 0};
  120.     mTextEditH = ::TEStyleNew(&viewRect, &viewRect);
  121.     
  122.     SetTextTraitsID(inTextTraitsID);
  123.     
  124.         // If word wrap is on, then the Image width is always the
  125.         // same as the Frame width, which forces text to wrap to
  126.         // the Frame.
  127.         
  128.         // If the Image width is zero (or negative), the user
  129.         // probably forgot to set it. To accommodate this error,
  130.         // we set the Image width to the Frame width. However, the
  131.         // Image will not change if the Frame resizes.
  132.     
  133.     if ((mTextAttributes & textAttr_WordWrap) ||
  134.         (mImageSize.width <= 0)) {
  135.         mImageSize.width = mFrameSize.width;
  136.     }
  137. }
  138.  
  139.  
  140. // ---------------------------------------------------------------------------
  141. //        • ~LStyledTextEdit
  142. // ---------------------------------------------------------------------------
  143. //    Destructor
  144.  
  145. LStyledTextEdit::~LStyledTextEdit()
  146. {
  147.     if (mTextEditH != nil) {
  148.         ::TEDispose(mTextEditH);
  149.     }
  150. }
  151.  
  152.  
  153. // ---------------------------------------------------------------------------
  154. //        • SetTextHandle
  155. // ---------------------------------------------------------------------------
  156. //    Set the text in the LTextEdit to the contents of the specified Handle
  157. //
  158. //    The LTextEdit copies the data in the Handle, so the caller retains
  159. //    ownership of the Handle (and should dispose of it as needed)
  160.  
  161. void
  162. LStyledTextEdit::SetTextHandle(
  163.     Handle    inTextH, TEStyleHandle inStylH)
  164. {
  165.     StHandleLocker    lock(inTextH);
  166.     
  167.     if( inStylH )
  168.     {
  169.         ::TEStyleInsert(*inTextH, ::GetHandleSize(inTextH), (StScrpHandle)inStylH, mTextEditH );
  170.         ::TECalText(mTextEditH);
  171.         AdjustImageToText();
  172.         Refresh();
  173.     }
  174.     else
  175.         SetTextPtr( *inTextH, ::GetHandleSize(inTextH) );
  176.         
  177. }    
  178.  
  179.  
  180.  
  181. void
  182. LStyledTextEdit::SetTextPtr(
  183.     Ptr        inTextP,
  184.     Int32    inTextLen)
  185. {
  186.     ::TESetText(inTextP, inTextLen, mTextEditH);
  187.     ::TECalText(mTextEditH);
  188.     AdjustImageToText();
  189.     Refresh();
  190. }
  191.  
  192.  
  193. // ---------------------------------------------------------------------------
  194. //        • GetMacTEH
  195. // ---------------------------------------------------------------------------
  196. //    Return a Handle to the text in the LStyledTextEdit
  197. //
  198. //    The Handle is the actual Handle used by the Toolbox StyledTextEdit record.
  199. //    Treat this Handle as read-only
  200.  
  201. Handle
  202. LStyledTextEdit::GetTextHandle()
  203. {
  204.     return (Handle) ::TEGetText(mTextEditH);
  205. }
  206.  
  207. StScrpHandle
  208. LStyledTextEdit::GetStyleScrapHandle()
  209. {
  210.     StScrpHandle     theStyleScrapHandle;
  211.     
  212.     short        oldStart,
  213.                 oldEnd;    
  214.     
  215.     oldStart = (**mTextEditH).selStart;
  216.     oldEnd   = (**mTextEditH).selEnd;
  217.     
  218.     (** mTextEditH).selStart = 0;
  219.     (** mTextEditH).selEnd = 32767;
  220.     theStyleScrapHandle = ::TEGetStyleScrapHandle(mTextEditH);
  221.     (**mTextEditH).selStart = oldStart;
  222.     (**mTextEditH).selEnd = oldEnd;
  223.  
  224.     return theStyleScrapHandle;
  225. }
  226.  
  227.  
  228. // ---------------------------------------------------------------------------
  229. //        • GetMacTEH
  230. // ---------------------------------------------------------------------------
  231. //    Return a Handle to the Mac StyledTextEdit Record associated with an StyledTextEdit
  232. //
  233. //    Caller may change record fields, and is responsible for redrawing the
  234. //    StyledTextEdit as necessary to reflect any changes. However, caller must
  235. //    not dispose of the TEHandle.
  236.  
  237. TEHandle
  238. LStyledTextEdit::GetMacTEH()
  239. {
  240.     return mTextEditH;
  241. }
  242.  
  243.  
  244. // ---------------------------------------------------------------------------
  245. //        • SetTextTraitsID
  246. // ---------------------------------------------------------------------------
  247. //    Specify the resource ID of the TextTraits for an StyledTextEdit
  248. //
  249. //    This function updates the line height to fit the text characteristics.
  250.  
  251. void
  252. LStyledTextEdit::SetTextTraitsID(
  253.     ResIDT    inTextTraitsID)
  254. {
  255.     mTextTraitsID = inTextTraitsID;
  256.     //UTextTraits::SetTETextTraits(mTextTraitsID, mTextEditH);
  257.     
  258.     SPoint32    scrollUnit;
  259.     scrollUnit.h = 4;
  260.     scrollUnit.v = 12; //(**mTextEditH).lineHeight;
  261.     SetScrollUnit(scrollUnit);
  262. }
  263.  
  264.  
  265. Boolean
  266. LStyledTextEdit::HasAttribute(
  267.     Uint16    inAttribute)
  268. {
  269.     return ((mTextAttributes & inAttribute) != 0);
  270. }
  271.  
  272.  
  273. Boolean
  274. LStyledTextEdit::FocusDraw()
  275. {
  276.     Boolean    focused = LView::FocusDraw();
  277.     if (focused) {
  278.         StColorPenState::Normalize();
  279.         //UTextTraits::SetPortTextTraits(mTextTraitsID);
  280.     }
  281.     
  282.     return focused;
  283. }
  284.  
  285.  
  286. // ---------------------------------------------------------------------------
  287. //        • DrawSelf
  288. // ---------------------------------------------------------------------------
  289. //    Draw a StyledTextEdit
  290.  
  291. void
  292. LStyledTextEdit::DrawSelf()
  293. {
  294.     Rect    frame;
  295.     CalcLocalFrameRect(frame);
  296.     
  297.         // A Mac TERec stores a pointer to its owner port  We have to
  298.         // change it to the current port in case we are drawing into
  299.         // a port that is not the owner port. This happens when we are
  300.         // printing or drawing into an offscreen port.
  301.         
  302.     GrafPtr    savePort = (**mTextEditH).inPort;
  303.     (**mTextEditH).inPort = UQDGlobals::GetCurrentPort();
  304.  
  305.     ::TEUpdate(&frame, mTextEditH);
  306.     
  307.     (**mTextEditH).inPort = savePort;
  308. }
  309.  
  310.  
  311. // ---------------------------------------------------------------------------
  312. //        • HideSelf
  313. // ---------------------------------------------------------------------------
  314. //    Hide an LStyledTextEdit. An invisible LStyledTextEdit can't be OnDuty.
  315.  
  316. void
  317. LStyledTextEdit::HideSelf()
  318. {
  319.     if (IsOnDuty()) {                // Shouldn't be on duty when invisible
  320.         SwitchTarget(GetSuperCommander());
  321.     }
  322. }
  323.  
  324.  
  325. // ---------------------------------------------------------------------------
  326. //        • ClickSelf
  327. // ---------------------------------------------------------------------------
  328. //    Respond to Click inside an StyledTextEdit
  329.  
  330. void
  331. LStyledTextEdit::ClickSelf(
  332.     const SMouseDownEvent    &inMouseDown)
  333. {
  334.     if (!HasAttribute(textAttr_Selectable)) {
  335.         return;
  336.     }
  337.  
  338.     if (!IsTarget()) {                // If not the Target, clicking in an
  339.                                     //   TextEdit makes it the Target.
  340.                                     // Since TEClick will set a new selection
  341.                                     //   range, clear the current selection
  342.                                     //   range to avoid an ugly flash.
  343.         ::TESetSelect(0, 0, mTextEditH);
  344.         SwitchTarget(this);
  345.     }
  346.     
  347.     if (IsTarget()) {
  348.         FocusDraw();
  349.         ::TEClick(inMouseDown.whereLocal,
  350.                     ((inMouseDown.macEvent.modifiers & shiftKey) != 0),
  351.                     mTextEditH);
  352.     }
  353. }
  354.  
  355.  
  356. // ---------------------------------------------------------------------------
  357. //        • AdjustCursorSelf
  358. // ---------------------------------------------------------------------------
  359. //    StyledTextEdit uses the standard I-Beam cursor
  360.  
  361. void
  362. LStyledTextEdit::AdjustCursorSelf(
  363.     Point                /* inPortPt */,
  364.     const EventRecord&    /* inMacEvent */)
  365. {
  366.     CursHandle    theCursH = ::GetCursor(iBeamCursor);
  367.     if (theCursH != nil) {
  368.         ::SetCursor(*theCursH);
  369.     }
  370. }
  371.  
  372.  
  373. Boolean
  374. LStyledTextEdit::ObeyCommand(
  375.     CommandT    inCommand,
  376.     void*        ioParam)
  377. {
  378.     Boolean        cmdHandled = true;
  379.     
  380.     switch (inCommand) {
  381.     
  382.         case cmd_Cut:
  383.             ::ZeroScrap();
  384.             ::TECut(mTextEditH);
  385.             ::TEToScrap();
  386.             AdjustImageToText();
  387.             UserChangedText();
  388.             break;
  389.             
  390.         case cmd_Copy:
  391.             ::ZeroScrap();
  392.             ::TECopy(mTextEditH);
  393.             ::TEToScrap();
  394.             break;
  395.             
  396.         case cmd_Paste:
  397.             ::TEFromScrap();
  398.             ::TEStylePaste(mTextEditH);
  399.             AdjustImageToText();
  400.             UserChangedText();
  401.             break;
  402.             
  403.         case cmd_Clear: {
  404.             ::TEDelete(mTextEditH);
  405.             AdjustImageToText();
  406.             UserChangedText();
  407.             break;
  408.         }
  409.             
  410.         case msg_TabSelect:
  411.             if (!IsEnabled()) {
  412.                 cmdHandled = false;
  413.                 break;
  414.             } // else FALL THRU to SelectAll()
  415.  
  416.         case cmd_SelectAll:
  417.             SelectAll();
  418.             break;
  419.             
  420.         default:
  421.             cmdHandled = LCommander::ObeyCommand(inCommand, ioParam);
  422.             break;
  423.     }
  424.     
  425.     return cmdHandled;
  426. }
  427.  
  428.  
  429. void
  430. LStyledTextEdit::FindCommandStatus(
  431.     CommandT    inCommand,
  432.     Boolean        &outEnabled,
  433.     Boolean        &outUsesMark,
  434.     Char16        &outMark,
  435.     Str255        outName)
  436. {
  437.     outUsesMark = false;
  438.  
  439.     switch (inCommand) {
  440.     
  441.         case cmd_Copy:                // Copy enabled if something is selected
  442.             outEnabled = ((**mTextEditH).selStart != (**mTextEditH).selEnd);
  443.             break;
  444.     
  445.         case cmd_Cut:                // Cut and Clear enabled if editabled
  446.         case cmd_Clear:                //   and something is selected
  447.             outEnabled = HasAttribute(textAttr_Editable) &&
  448.                             ((**mTextEditH).selStart != (**mTextEditH).selEnd);
  449.             break;
  450.                     
  451.         case cmd_Paste: {            // Pasted enabled if editable and
  452.             Int32    offset;            //   TEXT is on the Scrap
  453.             outEnabled = HasAttribute(textAttr_Editable) &&
  454.                             (::GetScrap(nil, 'TEXT', &offset) > 0);
  455.             break;
  456.         }
  457.         
  458.         case cmd_SelectAll:            // Check if any characters are present
  459.             outEnabled = HasAttribute(textAttr_Selectable) &&
  460.                             ((**mTextEditH).teLength > 0);
  461.                             
  462.             break;
  463.             
  464.         default:
  465.             LCommander::FindCommandStatus(inCommand, outEnabled,
  466.                                     outUsesMark, outMark, outName);
  467.             break;
  468.     }
  469. }
  470.  
  471.  
  472. // ---------------------------------------------------------------------------
  473. //        • HandleKeyPress
  474. // ---------------------------------------------------------------------------
  475. //    Handle key stroke directed at an StyledTextEdit
  476. //
  477. //    Return true if the StyledTextEdit handles the keystroke
  478.  
  479. Boolean
  480. LStyledTextEdit::HandleKeyPress(
  481.     const EventRecord&    inKeyEvent)
  482. {
  483.     Boolean        keyHandled = true;
  484.     EKeyStatus    theKeyStatus = keyStatus_Input;
  485.     Int16        theKey = inKeyEvent.message & charCodeMask;
  486.     
  487.     if (inKeyEvent.modifiers & cmdKey) {    // Always pass up when the command
  488.         theKeyStatus = keyStatus_PassUp;    //   key is down
  489.     } else {
  490.     
  491.         theKeyStatus = UKeyFilters::PrintingCharField(inKeyEvent);
  492.     }
  493.     
  494.     if ((theKeyStatus == keyStatus_PassUp) && (theKey == char_Return)) {
  495.         theKeyStatus = keyStatus_Input;        // Special case for Return key
  496.     }
  497.     
  498.     if (!HasAttribute(textAttr_Editable)) {    // Disallow editing
  499.         theKeyStatus = keyStatus_PassUp;
  500.     }
  501.     
  502.     short    lineCount = (**mTextEditH).nLines;
  503.     
  504.     switch (theKeyStatus) {
  505.     
  506.         case keyStatus_Input:
  507.         case keyStatus_TEDelete:
  508.             FocusDraw();
  509.             ::TEKey(theKey, mTextEditH);
  510.             UserChangedText();
  511.             break;
  512.             
  513.         case keyStatus_TECursor:
  514.             FocusDraw();
  515.             ::TEKey(theKey, mTextEditH);
  516.             break;
  517.             
  518.         case keyStatus_ExtraEdit:
  519.             if (theKey == char_FwdDelete) {
  520.                 FocusDraw();
  521.                 if (((**mTextEditH).selStart == (**mTextEditH).selEnd) &&
  522.                     ((**mTextEditH).selStart < (**mTextEditH).teLength) ) {
  523.                     ::TESetSelect((**mTextEditH).selStart + 1,
  524.                                     (**mTextEditH).selStart + 1,
  525.                                     mTextEditH);
  526.                     ::TEKey(char_Backspace, mTextEditH);
  527.                 } else {
  528.                     ::TEDelete(mTextEditH);
  529.                 }
  530.             
  531.             } else {
  532.                 keyHandled = LCommander::HandleKeyPress(inKeyEvent);
  533.             }
  534.             break;
  535.             
  536.         case keyStatus_Reject:
  537.             // +++ Do something
  538.             SysBeep(1);
  539.             break;
  540.             
  541.         case keyStatus_PassUp:
  542.             keyHandled = LCommander::HandleKeyPress(inKeyEvent);
  543.             break;
  544.     }
  545.     
  546.     if (lineCount != (**mTextEditH).nLines) {
  547.         AdjustImageToText();
  548.     }
  549.     
  550.     return keyHandled;
  551. }
  552.  
  553.  
  554. // ---------------------------------------------------------------------------
  555. //        • SelectAll
  556. // ---------------------------------------------------------------------------
  557. //    Select entire contents of an StyledTextEdit
  558.  
  559. void
  560. LStyledTextEdit::SelectAll()
  561. {
  562.     if (HasAttribute(textAttr_Selectable)) {
  563.         FocusDraw();
  564.         ::TESetSelect(0, 32767, mTextEditH);
  565.     }
  566. }
  567.  
  568. // ---------------------------------------------------------------------------
  569. //        • SelectNone
  570. // ---------------------------------------------------------------------------
  571. //    Select entire contents of an StyledTextEdit
  572.  
  573. void
  574. LStyledTextEdit::SelectNone()
  575. {
  576.     if (HasAttribute(textAttr_Selectable)) {
  577.         FocusDraw();
  578.         ::TESetSelect(0, 0, mTextEditH);
  579.     }
  580. }
  581.  
  582.  
  583. // ---------------------------------------------------------------------------
  584. //        • AlignTextEditRects
  585. // ---------------------------------------------------------------------------
  586. //    Align the view and destination rectangles of the Toolbox TextEdit
  587. //    record with the Frame of a TextEdit
  588.  
  589. void
  590. LStyledTextEdit::AlignTextEditRects()
  591. {
  592.     Rect    textFrame;
  593.     if (CalcLocalFrameRect(textFrame)) {
  594.                                     // TextEdit view rect same as Frame
  595.                                     //   in local coords
  596.         (**mTextEditH).viewRect = textFrame;
  597.         
  598.                                     // TextEdit dest rect same as Image
  599.                                     //   in local coords
  600.         SPoint32    imagePt = {0, 0};
  601.         ImageToLocalPoint(imagePt, topLeft((**mTextEditH).destRect));
  602.         
  603.                                     // Bottom of dest rect is ignored
  604.         imagePt.h = mImageSize.width;
  605.         ImageToLocalPoint(imagePt, botRight((**mTextEditH).destRect));
  606.         
  607.         ::TECalText(mTextEditH);    // Let TextEdit adjust line breaks
  608.     }
  609. }
  610.  
  611.  
  612. void
  613. LStyledTextEdit::AdjustImageToText()
  614. {
  615.     ResizeImageTo(mImageSize.width,
  616.                   ::TEGetHeight((**mTextEditH).nLines, 1, mTextEditH),
  617.                   false);
  618. }
  619.  
  620.  
  621. // ---------------------------------------------------------------------------
  622. //        • ResizeFrameBy
  623. // ---------------------------------------------------------------------------
  624. //    Change the Frame size by the specified amounts
  625. //
  626. //        inWidthDelta and inHeightDelta specify, in pixels, how much larger
  627. //        to make the Frame. Positive deltas increase the size, negative deltas
  628. //        reduce the size.
  629.  
  630. void
  631. LStyledTextEdit::ResizeFrameBy(
  632.     Int16        inWidthDelta,
  633.     Int16        inHeightDelta,
  634.     Boolean        inRefresh)
  635. {
  636.                                     // Resize Pane
  637.     LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  638.     
  639.     if (mTextAttributes & textAttr_WordWrap) {
  640.         ResizeImageTo(mFrameSize.width, mImageSize.height, false);
  641.     }
  642.     
  643.     AlignTextEditRects();
  644.     AdjustImageToText();
  645. }
  646.  
  647.  
  648. // ---------------------------------------------------------------------------
  649. //        • MoveBy
  650. // ---------------------------------------------------------------------------
  651. //    Move the location of the Frame by the specified amounts
  652. //
  653. //        inHorizDelta and inVertDelta specify, in pixels, how far to move the
  654. //        Frame (within its surrounding Image). Positive horiz deltas move to
  655. //        the right, negative to the left. Positive vert deltas move down,
  656. //        negative up.
  657.  
  658. void
  659. LStyledTextEdit::MoveBy(
  660.     Int32        inHorizDelta,
  661.     Int32        inVertDelta,
  662.     Boolean        inRefresh)
  663. {
  664.     LView::MoveBy(inHorizDelta, inVertDelta, inRefresh);
  665.     AlignTextEditRects();
  666. }
  667.  
  668.  
  669. // ---------------------------------------------------------------------------
  670. //        • ScrollImageBy
  671. // ---------------------------------------------------------------------------
  672. //    Scroll the Text
  673.  
  674. void
  675. LStyledTextEdit::ScrollImageBy(
  676.     Int32        inLeftDelta,        // Pixels to scroll horizontally
  677.     Int32        inTopDelta,            // Pixels to scroll vertically
  678.     Boolean        inRefresh)
  679. {
  680.     OffsetRect(&(**mTextEditH).viewRect, inLeftDelta, inTopDelta);
  681.  
  682.     LView::ScrollImageBy(inLeftDelta, inTopDelta, inRefresh);
  683. }
  684.  
  685.  
  686. // ---------------------------------------------------------------------------
  687. //        • BeTarget
  688. // ---------------------------------------------------------------------------
  689. //    StyledTextEdit is becoming the Target
  690.  
  691. void
  692. LStyledTextEdit::BeTarget()
  693. {
  694.     if (FocusDraw()) {                // Show active selection
  695.         ::TEActivate(mTextEditH);    // ??? What if we can't Focus ???
  696.     }
  697.     StartIdling();                    // Idle time used to flash the cursor
  698. }
  699.  
  700.  
  701. // ---------------------------------------------------------------------------
  702. //        • DontBeTarget
  703. // ---------------------------------------------------------------------------
  704. //    StyledTextEdit is no longer the Target
  705. //
  706. //    Remove StyledTextEdit from IdleQueue
  707.  
  708. void
  709. LStyledTextEdit::DontBeTarget()
  710. {
  711.     if (FocusDraw()) {                // Show inactive selection
  712.         ::TEDeactivate(mTextEditH);
  713.     }
  714.     StopIdling();                    // Stop flashing the cursor
  715. }
  716.  
  717.  
  718. // ---------------------------------------------------------------------------
  719. //        • SpendTime
  720. // ---------------------------------------------------------------------------
  721. //    Idle time: Flash the insertion cursor
  722.  
  723. void
  724. LStyledTextEdit::SpendTime(
  725.     const EventRecord&    /* inMacEvent */)
  726. {
  727.     if (FocusDraw() & IsVisible() & HasAttribute(textAttr_Selectable)) {
  728.         ::TEIdle(mTextEditH);
  729.     }
  730. }
  731.  
  732. // ---------------------------------------------------------------------------
  733. //        • UserChangedText
  734. // ---------------------------------------------------------------------------
  735. //    Text of TextEdit has changed as a result of user action
  736. //
  737. //    Override to validate field and/or dynamically update as the user
  738. //    types. This function is not called by SetDescriptor, which is typically
  739. //    used to programatically change the text.
  740.  
  741. void
  742. LStyledTextEdit::UserChangedText()
  743. {
  744. }
  745.  
  746.  
  747. SStyledTextEditUndoH
  748. LStyledTextEdit::SaveStateForUndo()
  749. {
  750.     SStyledTextEditUndoH    theUndoH = (SStyledTextEditUndoH)
  751.                                     ::NewHandle(sizeof(STextEditUndo));
  752.     ThrowIfMemFail_(theUndoH);
  753.     
  754.     Handle    currTextH = (**mTextEditH).hText;
  755.     ::HandToHand(&currTextH);
  756.     (**theUndoH).textH = currTextH;
  757.     (**theUndoH).selStart = (**mTextEditH).selStart;
  758.     (**theUndoH).selEnd = (**mTextEditH).selEnd;
  759.     
  760.     return theUndoH;
  761. }
  762.  
  763.  
  764. void
  765. LStyledTextEdit::SavePlace(
  766.     LStream        *outPlace)
  767. {
  768.     LView::SavePlace(outPlace);
  769.     
  770.     Rect    viewRect = (**mTextEditH).viewRect;
  771.     outPlace->WriteData(&viewRect, sizeof(Rect));
  772.     Rect    destRect = (**mTextEditH).destRect;
  773.     outPlace->WriteData(&destRect, sizeof(Rect));
  774. }
  775.  
  776.  
  777. void
  778. LStyledTextEdit::RestorePlace(
  779.     LStream        *inPlace)
  780. {
  781.     LView::RestorePlace(inPlace);
  782.  
  783.     Rect    viewRect;
  784.     inPlace->ReadData(&viewRect, sizeof(Rect));
  785.     (**mTextEditH).viewRect = viewRect;
  786.  
  787.     Rect    destRect;
  788.     inPlace->ReadData(&destRect, sizeof(Rect));
  789.     (**mTextEditH).destRect = destRect;
  790. }
  791.